// common/services/network/api_service.dart
import 'package:dio/dio.dart' hide Response, FormData, MultipartFile;
import 'package:get/get.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dio/dio.dart' as dio show Response, FormData, MultipartFile;
import 'package:rental/common/models/common/api_response.dart';
import 'network_config.dart';
import 'network_exception.dart';
import 'network_interceptor.dart';

/// 核心网络服务类 - 基于Dio和GetX的网络请求服务
class ApiService extends GetxService {
  late Dio _dio;
  final Connectivity _connectivity = Connectivity();
  
  // 取消令牌管理
  final Map<String, CancelToken> _cancelTokens = {};
  
  @override
  void onInit() {
    super.onInit();
    _initDio();
  }
  
  /// 初始化Dio配置
  void _initDio() {
    _dio = Dio();
    
    // 基础配置
    _dio.options = BaseOptions(
      baseUrl: NetworkConfig.fullBaseUrl,
      connectTimeout: Duration(milliseconds: NetworkConfig.connectTimeout),
      receiveTimeout: Duration(milliseconds: NetworkConfig.receiveTimeout),
      sendTimeout: Duration(milliseconds: NetworkConfig.sendTimeout),
      headers: NetworkConfig.defaultHeaders,
    );
    
    // 添加拦截器
    _dio.interceptors.addAll([
      AuthInterceptor(), // 认证拦截器
      RetryInterceptor( // 重试拦截器
        maxRetries: NetworkConfig.maxRetries,
        retryDelay: NetworkConfig.retryDelay,
      ),
      LoggingInterceptor(), // 日志拦截器
      CacheInterceptor(), // 缓存拦截器
    ]);
  }
  
  /// 检查网络连接
  Future<bool> _checkConnectivity() async {
    final connectivityResult = await _connectivity.checkConnectivity();
    return connectivityResult != ConnectivityResult.none;
  }
  
  /// 通用请求方法
  Future<ApiResponse<T>> _request<T>(
    String method,
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
    T Function(dynamic)? fromJson,
    String? tag,
    bool checkConnectivity = true,
  }) async {
    try {
      // 检查网络连接
      if (checkConnectivity && !await _checkConnectivity()) {
        return ApiResponse.error(message: '网络不可用，请检查网络连接');
      }
      
      // 创建取消令牌
      CancelToken? cancelToken;
      if (tag != null) {
        cancelToken = CancelToken();
        _cancelTokens[tag] = cancelToken;
      }
      
      // 合并请求头
      final requestHeaders = <String, dynamic>{
        ..._dio.options.headers,
        if (headers != null) ...headers,
      };
      
      // 发起请求
      final response = await _dio.request(
        path,
        data: data,
        queryParameters: queryParameters,
        options: Options(
          method: method,
          headers: requestHeaders,
        ),
        cancelToken: cancelToken,
      );
      
      // 移除取消令牌
      if (tag != null) {
        _cancelTokens.remove(tag);
      }
      
      // 处理响应
      return _handleResponse<T>(response, fromJson);
      
    } on DioException catch (e) {
      // 移除取消令牌
      if (tag != null) {
        _cancelTokens.remove(tag);
      }
      
      final networkException = NetworkException.fromDioException(e);
      return ApiResponse.error(
        message: networkException.message,
        code: networkException.code ?? -1,
        originalData: e.response?.data,
      );
    } catch (e) {
      // 移除取消令牌
      if (tag != null) {
        _cancelTokens.remove(tag);
      }
      
      return ApiResponse.error(
        message: '请求失败: $e',
        code: -1,
      );
    }
  }
  
  /// 处理响应数据
  ApiResponse<T> _handleResponse<T>(
    dio.Response response,
    T Function(dynamic)? fromJson,
  ) {
    try {
      final data = response.data;
      
      // 如果响应数据是Map，尝试解析为ApiResponse格式
      if (data is Map<String, dynamic>) {
        return ApiResponse.fromJson(data, fromJson);
      }
      
      // 如果响应数据不是Map，直接作为data返回
      T? parsedData;
      if (fromJson != null) {
        parsedData = fromJson(data);
      } else if (data is T) {
        parsedData = data;
      }
      
      return ApiResponse.success(
        data: parsedData as T,
        message: '请求成功',
        code: response.statusCode ?? 200,
      );
    } catch (e) {
      return ApiResponse.error(
        message: '数据解析失败: $e',
        code: response.statusCode ?? -1,
        originalData: response.data,
      );
    }
  }
  
  /// GET请求
  Future<ApiResponse<T>> get<T>(
    String path, {
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
    T Function(dynamic)? fromJson,
    String? tag,
  }) {
    return _request<T>(
      'GET',
      path,
      queryParameters: queryParameters,
      headers: headers,
      fromJson: fromJson,
      tag: tag,
    );
  }
  
  /// POST请求
  Future<ApiResponse<T>> post<T>(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
    T Function(dynamic)? fromJson,
    String? tag,
  }) {
    return _request<T>(
      'POST',
      path,
      data: data,
      queryParameters: queryParameters,
      headers: headers,
      fromJson: fromJson,
      tag: tag,
    );
  }
  
  /// PUT请求
  Future<ApiResponse<T>> put<T>(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
    T Function(dynamic)? fromJson,
    String? tag,
  }) {
    return _request<T>(
      'PUT',
      path,
      data: data,
      queryParameters: queryParameters,
      headers: headers,
      fromJson: fromJson,
      tag: tag,
    );
  }
  
  /// DELETE请求
  Future<ApiResponse<T>> delete<T>(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
    T Function(dynamic)? fromJson,
    String? tag,
  }) {
    return _request<T>(
      'DELETE',
      path,
      data: data,
      queryParameters: queryParameters,
      headers: headers,
      fromJson: fromJson,
      tag: tag,
    );
  }
  
  /// 上传文件
  Future<ApiResponse<T>> upload<T>(
    String path,
    String filePath, {
    String fileName = 'file',
    Map<String, dynamic>? data,
    T Function(dynamic)? fromJson,
    String? tag,
    ProgressCallback? onSendProgress,
  }) async {
    try {
      final formData = dio.FormData.fromMap({
        fileName: await dio.MultipartFile.fromFile(filePath),
        if (data != null) ...data,
      });
      
      return await post<T>(
        path,
        data: formData,
        fromJson: fromJson,
        tag: tag,
      );
    } catch (e) {
      return ApiResponse.error(message: '文件上传失败: $e');
    }
  }
  
  /// 下载文件
  Future<ApiResponse<String>> download(
    String path,
    String savePath, {
    Map<String, dynamic>? queryParameters,
    String? tag,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      // 检查网络连接
      if (!await _checkConnectivity()) {
        return ApiResponse.error(message: '网络不可用，请检查网络连接');
      }
      
      // 创建取消令牌
      CancelToken? cancelToken;
      if (tag != null) {
        cancelToken = CancelToken();
        _cancelTokens[tag] = cancelToken;
      }
      
      await _dio.download(
        path,
        savePath,
        queryParameters: queryParameters,
        cancelToken: cancelToken,
        onReceiveProgress: onReceiveProgress,
      );
      
      // 移除取消令牌
      if (tag != null) {
        _cancelTokens.remove(tag);
      }
      
      return ApiResponse.success(
        data: savePath,
        message: '下载成功',
      );
    } on DioException catch (e) {
      // 移除取消令牌
      if (tag != null) {
        _cancelTokens.remove(tag);
      }
      
      final networkException = NetworkException.fromDioException(e);
      return ApiResponse.error(message: networkException.message);
    } catch (e) {
      // 移除取消令牌
      if (tag != null) {
        _cancelTokens.remove(tag);
      }
      
      return ApiResponse.error(message: '下载失败: $e');
    }
  }
  
  /// 取消请求
  void cancelRequest(String tag) {
    final cancelToken = _cancelTokens[tag];
    if (cancelToken != null && !cancelToken.isCancelled) {
      cancelToken.cancel('请求已取消');
      _cancelTokens.remove(tag);
    }
  }
  
  /// 取消所有请求
  void cancelAllRequests() {
    for (final cancelToken in _cancelTokens.values) {
      if (!cancelToken.isCancelled) {
        cancelToken.cancel('所有请求已取消');
      }
    }
    _cancelTokens.clear();
  }
  
  /// 清除缓存
  void clearCache() {
    final cacheInterceptor = _dio.interceptors
        .whereType<CacheInterceptor>()
        .firstOrNull;
    cacheInterceptor?.clearCache();
  }
  
  @override
  void onClose() {
    cancelAllRequests();
    super.onClose();
  }
}


